const pageScroll = (function () {
  const fn = function (e) {
    e.preventDefault()
    e.stopPropagation()
  }
  let islock = false
  return {
    lock (el) {
      if (islock) return
      islock = true;
      (el || document).addEventListener('touchmove', fn)
    },
    unlock (el) {
      islock = false;
      (el || document).removeEventListener('touchmove', fn)
    }
  }
})()

const preventScroll = (function () {
  return {
    lock (el) {
      isIOS && addClass(el || document.body, 'g-fix-ios-prevent-scroll')
    },
    unlock (el) {
      isIOS && removeClass(el || document.body, 'g-fix-ios-prevent-scroll')
    }
  }
})()

const isIOS = !!(window.navigator && window.navigator.userAgent || '').match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)

const isColor = function (value) {
  const colorReg = /^#([a-fA-F0-9]){3}(([a-fA-F0-9]){3})?$/
  const rgbaReg = /^[rR][gG][bB][aA]\(\s*((25[0-5]|2[0-4]\d|1?\d{1,2})\s*,\s*){3}\s*(\.|\d+\.)?\d+\s*\)$/
  const rgbReg = /^[rR][gG][bB]\(\s*((25[0-5]|2[0-4]\d|1?\d{1,2})\s*,\s*){2}(25[0-5]|2[0-4]\d|1?\d{1,2})\s*\)$/
  return colorReg.test(value) || rgbaReg.test(value) || rgbReg.test(value)
}

const getScrollview = function (el) {
  let currentNode = el
  while (currentNode && currentNode.tagName !== 'HTML' && currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
    let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY
    if (overflowY === 'scroll' || overflowY === 'auto') {
      return currentNode
    }
    currentNode = currentNode.parentNode
  }
  return window
}

const checkInview = function (scrollView, el) {
  const contentHeight = scrollView === window ? document.body.offsetHeight : scrollView.offsetHeight
  const contentTop = scrollView === window ? 0 : scrollView.getBoundingClientRect().top
  const post = el.getBoundingClientRect().top - contentTop
  const posb = post + el.offsetHeight
  return (post >= 0 && post < contentHeight) || (posb > 0 && posb <= contentHeight)
}

const hasClass = function (elem, cls) {
  cls = cls || ''
  if (cls.replace(/\s/g, '').length === 0 || !elem) return false
  return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ')
}

const addClass = function (ele, cls) {
  if (!hasClass(ele, cls)) {
    ele.className = ele.className === '' ? cls : ele.className + ' ' + cls
  }
}

const removeClass = function (ele, cls) {
  if (hasClass(ele, cls)) {
    let newClass = ' ' + ele.className.replace(/[\t\r\n]/g, '') + ' '
    while (newClass.indexOf(' ' + cls + ' ') >= 0) {
      newClass = newClass.replace(' ' + cls + ' ', ' ')
    }
    ele.className = newClass.replace(/^\s+|\s+$/g, '')
  }
}

// Copy from iView. https://www.iviewui.com/
const scrollTop = function (el, from = 0, to, duration = 500, callback) {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = (
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function (callback) {
        return window.setTimeout(callback, 1000 / 60)
      }
    )
  }
  const difference = Math.abs(from - to)
  const step = Math.ceil(difference / duration * 50)

  function scroll (start, end, step) {
    if (start === end) {
      typeof callback === 'function' && callback()
      return
    }
    let d = (start + step > end) ? end : start + step
    if (start > end) {
      d = (start - step < end) ? end : start - step
    }
    if (el === window) {
      window.scrollTo(d, d)
    } else {
      el.scrollTop = d
    }
    window.requestAnimationFrame(() => scroll(d, end, step))
  }
  scroll(from, to, step)
}

export {
  pageScroll,
  preventScroll,
  isIOS,
  isColor,
  getScrollview,
  checkInview,
  addClass,
  removeClass,
  scrollTop
}
